package peer.dstdb;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.BitSet;

import peer.share.CacheFileInfo;

public class SourceNode {
	int sourceSessionId;
	InetAddress assistNodeIp;
	int assistNodePort;
	int assistSessionId;
	public BitSet blockBit=new BitSet();
	int blockSum;
	CacheFileInfo cfi;
	long updateTime=peer.Config.getVTime();
	InetAddress lanIp;
	InetAddress outIp;
	SourceNode(int sourceSessionId,InetAddress assistNodeIp,int assistNodePort,int assistSessionId,InetAddress outIp,InetAddress lanIp){
		this.sourceSessionId=sourceSessionId;
		this.assistNodeIp=assistNodeIp;
		this.assistNodePort=assistNodePort;
		this.assistSessionId=assistSessionId;
		this.lanIp=lanIp;
		this.outIp=outIp;
		cfi=new CacheFileInfo();
		blockBit=new BitSet(blockSum);
	}
	
	SourceNode(byte[] data) throws UnknownHostException{
		sourceSessionId=peer.tools.ByteIntSwitch.toInt(data, 8);
		updateTime=peer.tools.ByteLongSwitch.toLong(data, 0);
		byte[] b=new byte[4];
		System.arraycopy(data, 4+8, b, 0, 4);
		assistNodeIp=InetAddress.getByAddress(b);
		assistNodePort=peer.tools.ByteIntSwitch.toInt(data, 8+8);
		assistSessionId=peer.tools.ByteIntSwitch.toInt(data, 12+8);
		
		byte[] b2=new byte[4];
		System.arraycopy(data, 12+8+4, b2, 0, 4);
		outIp=InetAddress.getByAddress(b2);
		byte[] cfb=new byte[data.length-16-8-4];
		System.arraycopy(data, 16+8+4, cfb, 0, cfb.length);
		cfi=new CacheFileInfo(cfb);
	}
	
	byte[] getByte(){
		byte[] cfb=cfi.getByte();
		byte[] data=new byte[16+cfb.length+8+4];
		peer.tools.ByteLongSwitch.toByteArray(updateTime, data,0);
		peer.tools.ByteIntSwitch.toByteArray(sourceSessionId, data, 0+8);
		System.arraycopy(assistNodeIp.getAddress(), 0, data, 4+8, 4);
		peer.tools.ByteIntSwitch.toByteArray(assistNodePort, data, 8+8);
		peer.tools.ByteIntSwitch.toByteArray(assistSessionId, data, 12+8);
		
		System.arraycopy(outIp.getAddress(), 0, data, 16+8, 4);
		System.arraycopy(cfb, 0, data, 16+8+4, cfb.length);
		return data;
	}
	
	CacheFileInfo getCancheFileInfo(){
		return cfi;
	}
	
	void addFrag(int offset,int length){
		for(int i=0;i<length;i++){
			cfi.setBlock(offset+i);
		}
		update();
	}
	
	boolean containsBlock(int blockNum){
		return cfi.containsBlock(blockNum);
	}
	
	void update(){
		updateTime=peer.Config.getVTime();
	}
}
